package org.lex.dbq.util;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.io.IOCase;
import org.apache.commons.io.filefilter.SuffixFileFilter;
import org.lex.dbq.model.bo.DriverConfig;
import org.lex.io.utils.FileUtils;
import org.lex.jdbc.driver.DriverUtils;
import org.lex.lang.AggregateException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DriverLoader {
	private static final FileFilter filter = new SuffixFileFilter(new String[] { ".jar", ".zip" }, IOCase.INSENSITIVE);
	private static Logger log = LoggerFactory.getLogger(DriverUtils.class);

	public List<String> loadDriverClassNames(Collection<File> loc) throws AggregateException {
		Collection<Class<?>> drivers = loadDriverClasses(loc);
		List<String> driverNames = new ArrayList<String>(drivers.size());
		for (Class<?> c : drivers) {
			driverNames.add(c.getName());
		}
		return driverNames;
	}

	public Collection<Class<?>> loadDriverClasses(Collection<File> loc) throws AggregateException {
		File[] jars = this.getJarFiles(loc).toArray(new File[0]);
		Collection<Class<?>> drivers = new ArrayList<Class<?>>();
		DriverUtils.loadDrivers(drivers, jars);
		return drivers;
	}

	public boolean loadDriver(DriverConfig dc) throws AggregateException {
		Collection<Class<?>> drivers = loadDriverClasses(dc.getClasspath().getLocations());
		for (Class<?> clz : drivers) {
			String className = clz.getCanonicalName();
			if (className.equals(dc.getClassName())) {
				log.info("Driver " + dc + "load success: driverClass=" + clz);
				return true;
			}
		}
		return false;
	}

	private List<File> getJarFiles(Collection<File> loc) {
		List<File> files = new ArrayList<File>();
		for (File e : loc) {
			if (e.isFile()) {
				files.add(e);
			} else {
				files.addAll(FileUtils.listFiles(e, filter));
			}
		}
		return files;
	}
}
